#!/bin/bash
###############################################################################
#       脚本名称: utils_file.sh
#       功能描述: 文件及文件夹处理工具模块，提供纯粹的文件及文件夹操作功能。
#       作者: 林再来
#       日期: 2025-10-16
#       版本: 1.0
#       功能:
#           1、文件复制、移动、删除操作(支持备份)
#           2、文件权限管理(权限查询、修改、恢复)
#           3、文件内容处理(读取、追加、替换、比较)
#           4、目录遍历和搜索(递归查找、过滤)
#           5、文件/目录校验函数
#       依赖(插件/命令):
#           1、bash
#           2、cp, mv, rm (文件操作)
#           3、chmod, chown (权限管理)
#           4、find, grep (搜索功能)
###############################################################################

# 防止重复加载
if [[ -n "${utils_file_sh_loaded:-}" ]]; then
    return 0
fi
readonly utils_file_sh_loaded=1

# 注意：不使用严格模式，避免影响交互式 shell

# 获取脚本目录和项目根目录(如果尚未定义)
if [[ -z "${script_dir:-}" ]]; then
    script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    readonly script_dir
fi

if [[ -z "${project_root:-}" ]]; then
    project_root="$(cd "${script_dir}/../.." && pwd)"
    readonly project_root
fi

###############################################################################
# 全局常量
###############################################################################

readonly UTILS_FILE_BACKUP_SUFFIX=".bak"
readonly UTILS_FILE_TEMP_DIR="${TMPDIR:-/tmp}/utils_file"

###############################################################################
# 全局变量
###############################################################################

utils_file_backup_enabled="${utils_file_backup_enabled:-true}"
utils_file_verbose="${utils_file_verbose:-false}"

###############################################################################
# 文件校验函数
###############################################################################

# 函数: 校验文件是否存在
# 参数: $1 - 文件路径; $2 - 参数名称(用于错误信息)
# 返回: 0-文件存在, 66-文件不存在
# 说明: 仅检查文件存在性，不检查可读性
function validate_file_exists() {
    local file_path="$1"
    local name="${2:-file}"

    # 如果路径为空，视为通过(可选参数场景)
    if [[ -z "$file_path" ]]; then
        return 0
    fi

    if [[ ! -f "$file_path" ]]; then
        printf "%s\n" "错误: 文件不存在(${name}): ${file_path}" >&2
        return 66
    fi
    return 0
}

# 函数: 校验文件是否可读
# 参数: $1 - 文件路径; $2 - 参数名称(用于错误信息)
# 返回: 0-文件可读, 66-文件不可读或不存在
# 说明: 检查文件是否存在且可读
function validate_file_readable() {
    local file_path="$1"
    local name="${2:-file}"

    # 如果路径为空，视为通过(可选参数场景)
    if [[ -z "$file_path" ]]; then
        return 0
    fi

    # 先检查文件是否存在
    if [[ ! -f "$file_path" ]]; then
        printf "%s\n" "错误: 文件不存在(${name}): ${file_path}" >&2
        return 66
    fi

    # 再检查文件是否可读
    if [[ ! -r "$file_path" ]]; then
        printf "%s\n" "错误: 文件不可读(${name}): ${file_path}" >&2
        return 66
    fi

    return 0
}

# 函数: 校验目录是否存在
# 参数: $1 - 目录路径; $2 - 参数名称(用于错误信息)
# 返回: 0-目录存在, 66-目录不存在
# 说明: 仅检查目录存在性
function validate_dir_exists() {
    local dir_path="$1"
    local name="${2:-directory}"

    # 如果路径为空，视为通过(可选参数场景)
    if [[ -z "$dir_path" ]]; then
        return 0
    fi

    if [[ ! -d "$dir_path" ]]; then
        printf "%s\n" "错误: 目录不存在(${name}): ${dir_path}" >&2
        return 66
    fi
    return 0
}

# 函数: 校验目录是否可写
# 参数: $1 - 目录路径; $2 - 参数名称(用于错误信息)
# 返回: 0-目录可写, 66-目录不存在, 73-目录不可写
# 说明: 检查目录是否存在且可写
function validate_dir_writable() {
    local dir_path="$1"
    local name="${2:-directory}"

    # 如果路径为空，视为通过(可选参数场景)
    if [[ -z "$dir_path" ]]; then
        return 0
    fi

    # 先检查目录是否存在
    if [[ ! -d "$dir_path" ]]; then
        printf "%s\n" "错误: 目录不存在(${name}): ${dir_path}" >&2
        return 66
    fi

    # 再检查目录是否可写
    if [[ ! -w "$dir_path" ]]; then
        printf "%s\n" "错误: 目录不可写(${name}): ${dir_path}" >&2
        return 73
    fi

    return 0
}

###############################################################################
# 1. 文件复制、移动、删除操作
###############################################################################

# 函数: 复制文件或目录
# 参数: $1 - 源路径, $2 - 目标路径, $3 - 选项(可选: -r递归, -f强制, -b备份)
# 返回: 0-成功, 1-失败
# 说明: 支持文件和目录复制，可选备份原文件
function utils_file_copy() {
    local source="$1"
    local target="$2"
    local options="${3:-}"
    
    if [[ -z "$source" ]] || [[ -z "$target" ]]; then
        log_error "utils_file" "错误: 缺少参数: 源路径和目标路径"
        return 1
    fi
    
    if [[ ! -e "$source" ]]; then
        log_error "utils_file" "错误: 源路径不存在: $source"
        return 1
    fi
    
    log_debug "utils_file" "复制: $source -> $target (选项: $options)"
    
    # 构建cp命令参数
    local cp_args=()
    
    # 解析选项
    if [[ "$options" == *r* ]] || [[ -d "$source" ]]; then
        cp_args+=("-r")
    fi
    
    if [[ "$options" == *f* ]]; then
        cp_args+=("-f")
    fi
    
    # 如果目标文件存在且启用备份
    if [[ "$options" == *b* ]] && [[ -e "$target" ]]; then
        local backup_file="${target}${UTILS_FILE_BACKUP_SUFFIX}.$(date +%s)"
        log_info "utils_file" "备份目标文件: $target -> $backup_file"
        cp -r "$target" "$backup_file" || {
            log_error "utils_file" "错误: 备份失败"
            return 1
        }
    fi
    
    # 执行复制
    if cp "${cp_args[@]}" "$source" "$target" 2>/dev/null; then
        log_info "utils_file" "复制成功: $source -> $target"
        return 0
    else
        log_error "utils_file" "错误: 复制失败"
        return 1
    fi
}

# 函数: 移动文件或目录
# 参数: $1 - 源路径, $2 - 目标路径, $3 - 选项(可选: -f强制, -b备份)
# 返回: 0-成功, 1-失败
# 说明: 支持文件和目录移动，可选备份目标文件
function utils_file_move() {
    local source="$1"
    local target="$2"
    local options="${3:-}"
    
    if [[ -z "$source" ]] || [[ -z "$target" ]]; then
        log_error "utils_file" "错误: 缺少参数: 源路径和目标路径"
        return 1
    fi
    
    if [[ ! -e "$source" ]]; then
        log_error "utils_file" "错误: 源路径不存在: $source"
        return 1
    fi
    
    log_debug "utils_file" "移动: $source -> $target (选项: $options)"
    
    # 构建mv命令参数
    local mv_args=()
    
    if [[ "$options" == *f* ]]; then
        mv_args+=("-f")
    fi
    
    # 如果目标文件存在且启用备份
    if [[ "$options" == *b* ]] && [[ -e "$target" ]]; then
        local backup_file="${target}${UTILS_FILE_BACKUP_SUFFIX}.$(date +%s)"
        log_info "utils_file" "备份目标文件: $target -> $backup_file"
        cp -r "$target" "$backup_file" || {
            log_error "utils_file" "错误: 备份失败"
            return 1
        }
    fi
    
    # 执行移动
    if mv "${mv_args[@]}" "$source" "$target" 2>/dev/null; then
        log_info "utils_file" "移动成功: $source -> $target"
        return 0
    else
        log_error "utils_file" "错误: 移动失败"
        return 1
    fi
}

# 函数: 删除文件或目录
# 参数: $1 - 路径, $2 - 选项(可选: -r递归, -f强制, -b备份)
# 返回: 0-成功, 1-失败
# 说明: 支持安全删除，可选备份功能
function utils_file_remove() {
    local path="$1"
    local options="${2:-}"
    
    if [[ -z "$path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 路径"
        return 1
    fi
    
    if [[ ! -e "$path" ]]; then
        log_warn "utils_file" "警告: 路径不存在: $path"
        return 0
    fi
    
    # 安全检查：防止删除根目录或重要系统目录
    local abs_path
    abs_path=$(realpath "$path" 2>/dev/null) || abs_path="$path"
    
    if [[ "$abs_path" == "/" ]] || [[ "$abs_path" == "/bin" ]] || \
       [[ "$abs_path" == "/usr" ]] || [[ "$abs_path" == "/etc" ]] || \
       [[ "$abs_path" == "/home" ]] || [[ "$abs_path" == "/root" ]]; then
        log_error "utils_file" "错误: 拒绝删除系统关键目录: $abs_path"
        return 1
    fi
    
    log_debug "utils_file" "删除: $path (选项: $options)"
    
    # 如果启用备份
    if [[ "$options" == *b* ]]; then
        local backup_file="${path}${UTILS_FILE_BACKUP_SUFFIX}.$(date +%s)"
        log_info "utils_file" "备份文件: $path -> $backup_file"
        cp -r "$path" "$backup_file" || {
            log_error "utils_file" "错误: 备份失败"
            return 1
        }
    fi
    
    # 构建rm命令参数
    local rm_args=()
    
    if [[ "$options" == *r* ]] || [[ -d "$path" ]]; then
        rm_args+=("-r")
    fi
    
    if [[ "$options" == *f* ]]; then
        rm_args+=("-f")
    fi
    
    # 执行删除
    if rm "${rm_args[@]}" "$path" 2>/dev/null; then
        log_info "utils_file" "删除成功: $path"
        return 0
    else
        log_error "utils_file" "错误: 删除失败"
        return 1
    fi
}

###############################################################################
# 2. 文件权限管理
###############################################################################

# 函数: 获取文件权限
# 参数: $1 - 文件路径
# 返回: 0-成功, 1-失败
# 输出: 文件权限(数字格式，如: 644)
function utils_file_get_permission() {
    local file_path="$1"
    
    if [[ -z "$file_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径"
        return 1
    fi
    
    if [[ ! -e "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    log_debug "utils_file" "获取文件权限: $file_path"
    
    # 获取文件权限(数字格式)
    local permission
    if permission=$(stat -c "%a" "$file_path" 2>/dev/null) || \
       permission=$(stat -f "%OLp" "$file_path" 2>/dev/null); then
        echo "$permission"
        return 0
    else
        log_error "utils_file" "错误: 获取权限失败"
        return 1
    fi
}

# 函数: 设置文件权限
# 参数: $1 - 文件路径, $2 - 权限(如: 644, 755), $3 - 选项(可选: -r递归)
# 返回: 0-成功, 1-失败
# 说明: 修改文件或目录权限
function utils_file_set_permission() {
    local file_path="$1"
    local permission="$2"
    local options="${3:-}"
    
    if [[ -z "$file_path" ]] || [[ -z "$permission" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径和权限"
        return 1
    fi
    
    if [[ ! -e "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    # 验证权限格式(3位或4位数字)
    if [[ ! "$permission" =~ ^[0-7]{3,4}$ ]]; then
        log_error "utils_file" "错误: 权限格式无效: $permission (应为3或4位八进制数)"
        return 1
    fi
    
    log_debug "utils_file" "设置文件权限: $file_path -> $permission (选项: $options)"
    
    # 构建chmod命令参数
    local chmod_args=()
    
    if [[ "$options" == *r* ]] && [[ -d "$file_path" ]]; then
        chmod_args+=("-R")
    fi
    
    chmod_args+=("$permission" "$file_path")
    
    # 执行权限修改
    if chmod "${chmod_args[@]}" 2>/dev/null; then
        log_info "utils_file" "权限修改成功: $file_path -> $permission"
        return 0
    else
        log_error "utils_file" "错误: 权限修改失败"
        return 1
    fi
}

# 函数: 获取文件所有者
# 参数: $1 - 文件路径
# 返回: 0-成功, 1-失败
# 输出: 所有者(格式: user:group)
function utils_file_get_owner() {
    local file_path="$1"
    
    if [[ -z "$file_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径"
        return 1
    fi
    
    if [[ ! -e "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    log_debug "utils_file" "获取文件所有者: $file_path"
    
    # 获取所有者和组
    local owner
    if owner=$(stat -c "%U:%G" "$file_path" 2>/dev/null) || \
       owner=$(stat -f "%Su:%Sg" "$file_path" 2>/dev/null); then
        echo "$owner"
        return 0
    else
        log_error "utils_file" "错误: 获取所有者失败"
        return 1
    fi
}

# 函数: 设置文件所有者
# 参数: $1 - 文件路径, $2 - 所有者(格式: user:group 或 user), $3 - 选项(可选: -r递归)
# 返回: 0-成功, 1-失败
# 说明: 修改文件或目录所有者
function utils_file_set_owner() {
    local file_path="$1"
    local owner="$2"
    local options="${3:-}"
    
    if [[ -z "$file_path" ]] || [[ -z "$owner" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径和所有者"
        return 1
    fi
    
    if [[ ! -e "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    log_debug "utils_file" "设置文件所有者: $file_path -> $owner (选项: $options)"
    
    # 构建chown命令参数
    local chown_args=()
    
    if [[ "$options" == *r* ]] && [[ -d "$file_path" ]]; then
        chown_args+=("-R")
    fi
    
    chown_args+=("$owner" "$file_path")
    
    # 执行所有者修改
    if chown "${chown_args[@]}" 2>/dev/null; then
        log_info "utils_file" "所有者修改成功: $file_path -> $owner"
        return 0
    else
        log_error "utils_file" "错误: 所有者修改失败"
        return 1
    fi
}

###############################################################################
# 3. 文件内容处理
###############################################################################

# 函数: 读取文件内容
# 参数: $1 - 文件路径, $2 - 选项(可选: -n行数, -t去除空白)
# 返回: 0-成功, 1-失败
# 输出: 文件内容
function utils_file_read() {
    local file_path="$1"
    local options="${2:-}"
    
    if [[ -z "$file_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径"
        return 1
    fi
    
    if [[ ! -f "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    if [[ ! -r "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不可读: $file_path"
        return 1
    fi
    
    log_debug "utils_file" "读取文件内容: $file_path (选项: $options)"
    
    # 解析行数限制
    local line_limit=""
    if [[ "$options" =~ -n([0-9]+) ]]; then
        line_limit="${BASH_REMATCH[1]}"
    fi
    
    # 读取文件
    local content
    if [[ -n "$line_limit" ]]; then
        content=$(head -n "$line_limit" "$file_path")
    else
        content=$(cat "$file_path")
    fi
    
    # 去除空白选项
    if [[ "$options" == *t* ]]; then
        content=$(echo "$content" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    fi
    
    echo "$content"
    return 0
}

# 函数: 写入内容到文件
# 参数: $1 - 文件路径, $2 - 内容, $3 - 选项(可选: -a追加, -b备份)
# 返回: 0-成功, 1-失败
# 说明: 支持覆盖和追加模式
function utils_file_write() {
    local file_path="$1"
    local content="$2"
    local options="${3:-}"
    
    if [[ -z "$file_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径"
        return 1
    fi
    
    log_debug "utils_file" "写入文件内容: $file_path (选项: $options)"
    
    # 如果文件存在且启用备份
    if [[ "$options" == *b* ]] && [[ -f "$file_path" ]]; then
        local backup_file="${file_path}${UTILS_FILE_BACKUP_SUFFIX}.$(date +%s)"
        log_info "utils_file" "备份文件: $file_path -> $backup_file"
        cp "$file_path" "$backup_file" || {
            log_error "utils_file" "错误: 备份失败"
            return 1
        }
    fi
    
    # 执行写入
    if [[ "$options" == *a* ]]; then
        # 追加模式
        if echo "$content" >> "$file_path" 2>/dev/null; then
            log_info "utils_file" "追加内容成功: $file_path"
            return 0
        else
            log_error "utils_file" "错误: 追加内容失败"
            return 1
        fi
    else
        # 覆盖模式
        if echo "$content" > "$file_path" 2>/dev/null; then
            log_info "utils_file" "写入内容成功: $file_path"
            return 0
        else
            log_error "utils_file" "错误: 写入内容失败"
            return 1
        fi
    fi
}

# 函数: 在文件中查找内容
# 参数: $1 - 文件路径, $2 - 搜索模式(正则), $3 - 选项(可选: -i忽略大小写, -c仅计数)
# 返回: 0-找到, 1-未找到或失败
# 输出: 匹配的行或计数
function utils_file_search() {
    local file_path="$1"
    local pattern="$2"
    local options="${3:-}"
    
    if [[ -z "$file_path" ]] || [[ -z "$pattern" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径和搜索模式"
        return 1
    fi
    
    if [[ ! -f "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    log_debug "utils_file" "搜索文件内容: $file_path -> $pattern (选项: $options)"
    
    # 构建grep命令参数
    local grep_args=()
    
    if [[ "$options" == *i* ]]; then
        grep_args+=("-i")
    fi
    
    if [[ "$options" == *c* ]]; then
        grep_args+=("-c")
    fi
    
    grep_args+=("$pattern" "$file_path")
    
    # 执行搜索
    if grep "${grep_args[@]}" 2>/dev/null; then
        return 0
    else
        return 1
    fi
}

# 函数: 替换文件中的内容
# 参数: $1 - 文件路径, $2 - 搜索模式, $3 - 替换内容, $4 - 选项(可选: -i忽略大小写, -b备份)
# 返回: 0-成功, 1-失败
# 说明: 使用sed进行内容替换
function utils_file_replace() {
    local file_path="$1"
    local pattern="$2"
    local replacement="$3"
    local options="${4:-}"
    
    if [[ -z "$file_path" ]] || [[ -z "$pattern" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件路径和搜索模式"
        return 1
    fi
    
    if [[ ! -f "$file_path" ]]; then
        log_error "utils_file" "错误: 文件不存在: $file_path"
        return 1
    fi
    
    log_debug "utils_file" "替换文件内容: $file_path -> s/$pattern/$replacement/ (选项: $options)"
    
    # 如果启用备份
    if [[ "$options" == *b* ]]; then
        local backup_file="${file_path}${UTILS_FILE_BACKUP_SUFFIX}.$(date +%s)"
        log_info "utils_file" "备份文件: $file_path -> $backup_file"
        cp "$file_path" "$backup_file" || {
            log_error "utils_file" "错误: 备份失败"
            return 1
        }
    fi
    
    # 构建sed命令参数
    local sed_flags="g"
    if [[ "$options" == *i* ]]; then
        sed_flags="${sed_flags}I"
    fi
    
    # 执行替换
    if sed -i "s/${pattern}/${replacement}/${sed_flags}" "$file_path" 2>/dev/null; then
        log_info "utils_file" "替换内容成功: $file_path"
        return 0
    else
        log_error "utils_file" "错误: 替换内容失败"
        return 1
    fi
}

# 函数: 比较两个文件
# 参数: $1 - 文件1路径, $2 - 文件2路径
# 返回: 0-相同, 1-不同或失败
# 输出: 差异内容(如果不同)
function utils_file_compare() {
    local file1="$1"
    local file2="$2"
    
    if [[ -z "$file1" ]] || [[ -z "$file2" ]]; then
        log_error "utils_file" "错误: 缺少参数: 文件1和文件2路径"
        return 1
    fi
    
    if [[ ! -f "$file1" ]]; then
        log_error "utils_file" "错误: 文件1不存在: $file1"
        return 1
    fi
    
    if [[ ! -f "$file2" ]]; then
        log_error "utils_file" "错误: 文件2不存在: $file2"
        return 1
    fi
    
    log_debug "utils_file" "比较文件: $file1 vs $file2"
    
    # 使用diff比较
    if diff -u "$file1" "$file2" 2>/dev/null; then
        log_info "utils_file" "文件相同"
        return 0
    else
        log_info "utils_file" "文件不同"
        return 1
    fi
}

###############################################################################
# 4. 目录遍历和搜索
###############################################################################

# 函数: 查找文件
# 参数: $1 - 搜索目录, $2 - 文件名模式, $3 - 选项(可选: -t类型[f/d], -d深度)
# 返回: 0-找到, 1-未找到或失败
# 输出: 找到的文件路径列表
function utils_file_find() {
    local search_dir="$1"
    local pattern="${2:-*}"
    local options="${3:-}"
    
    if [[ -z "$search_dir" ]]; then
        log_error "utils_file" "错误: 缺少参数: 搜索目录"
        return 1
    fi
    
    if [[ ! -d "$search_dir" ]]; then
        log_error "utils_file" "错误: 搜索目录不存在: $search_dir"
        return 1
    fi
    
    log_debug "utils_file" "查找文件: $search_dir -> $pattern (选项: $options)"
    
    # 构建find命令参数
    local find_args=("$search_dir")
    
    # 解析深度限制
    if [[ "$options" =~ -d([0-9]+) ]]; then
        local depth="${BASH_REMATCH[1]}"
        find_args+=("-maxdepth" "$depth")
    fi
    
    # 解析类型
    if [[ "$options" =~ -t([fd]) ]]; then
        local type="${BASH_REMATCH[1]}"
        find_args+=("-type" "$type")
    fi
    
    # 添加名称模式
    find_args+=("-name" "$pattern")
    
    # 执行查找
    if find "${find_args[@]}" 2>/dev/null; then
        return 0
    else
        return 1
    fi
}

# 函数: 递归列出目录内容
# 参数: $1 - 目录路径, $2 - 选项(可选: -a显示隐藏文件, -d仅显示目录, -f仅显示文件)
# 返回: 0-成功, 1-失败
# 输出: 目录树结构
function utils_file_list() {
    local dir_path="$1"
    local options="${2:-}"
    
    if [[ -z "$dir_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 目录路径"
        return 1
    fi
    
    if [[ ! -d "$dir_path" ]]; then
        log_error "utils_file" "错误: 目录不存在: $dir_path"
        return 1
    fi
    
    log_debug "utils_file" "列出目录内容: $dir_path (选项: $options)"
    
    # 构建find命令参数
    local find_args=("$dir_path")
    
    # 解析选项
    if [[ "$options" == *d* ]]; then
        find_args+=("-type" "d")
    elif [[ "$options" == *f* ]]; then
        find_args+=("-type" "f")
    fi
    
    # 是否显示隐藏文件
    if [[ "$options" != *a* ]]; then
        find_args+=("!" "-name" ".*")
    fi
    
    # 执行列出
    if find "${find_args[@]}" 2>/dev/null; then
        return 0
    else
        log_error "utils_file" "错误: 列出目录失败"
        return 1
    fi
}

# 函数: 获取目录大小
# 参数: $1 - 目录路径, $2 - 选项(可选: -h人类可读格式)
# 返回: 0-成功, 1-失败
# 输出: 目录大小
function utils_file_dirsize() {
    local dir_path="$1"
    local options="${2:-}"
    
    if [[ -z "$dir_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 目录路径"
        return 1
    fi
    
    if [[ ! -d "$dir_path" ]]; then
        log_error "utils_file" "错误: 目录不存在: $dir_path"
        return 1
    fi
    
    log_debug "utils_file" "获取目录大小: $dir_path (选项: $options)"
    
    # 构建du命令参数
    local du_args=("-s")
    
    if [[ "$options" == *h* ]]; then
        du_args+=("-h")
    fi
    
    du_args+=("$dir_path")
    
    # 执行计算
    if du "${du_args[@]}" 2>/dev/null | awk '{print $1}'; then
        return 0
    else
        log_error "utils_file" "错误: 获取目录大小失败"
        return 1
    fi
}

# 函数: 创建目录(支持递归)
# 参数: $1 - 目录路径, $2 - 权限(可选，如: 755)
# 返回: 0-成功, 1-失败
# 说明: 如果目录已存在则直接返回成功
function utils_file_mkdir() {
    local dir_path="$1"
    local permission="${2:-755}"
    
    if [[ -z "$dir_path" ]]; then
        log_error "utils_file" "错误: 缺少参数: 目录路径"
        return 1
    fi
    
    # 目录已存在
    if [[ -d "$dir_path" ]]; then
        log_debug "utils_file" "目录已存在: $dir_path"
        return 0
    fi
    
    log_debug "utils_file" "创建目录: $dir_path (权限: $permission)"
    
    # 创建目录
    if mkdir -p "$dir_path" 2>/dev/null; then
        # 设置权限
        if chmod "$permission" "$dir_path" 2>/dev/null; then
            log_info "utils_file" "目录创建成功: $dir_path"
            return 0
        else
            log_warn "utils_file" "警告: 目录创建成功但权限设置失败: $dir_path"
            return 0
        fi
    else
        log_error "utils_file" "错误: 目录创建失败: $dir_path"
        return 1
    fi
}

###############################################################################
# 辅助函数(日志占位符)
###############################################################################

# 如果外部没有定义日志函数，使用简单的echo实现
if ! declare -F log_debug >/dev/null 2>&1; then
    function log_debug() {
        local module="${1:-}"
        shift
        [[ "${utils_file_verbose}" == "true" ]] && echo "[DEBUG] [$module] $*" >&2
    }
fi

if ! declare -F log_info >/dev/null 2>&1; then
    function log_info() {
        local module="${1:-}"
        shift
        echo "[INFO]  [$module] $*" >&2
    }
fi

if ! declare -F log_warn >/dev/null 2>&1; then
    function log_warn() {
        local module="${1:-}"
        shift
        echo "[WARN]  [$module] $*" >&2
    }
fi

if ! declare -F log_error >/dev/null 2>&1; then
    function log_error() {
        local module="${1:-}"
        shift
        echo "[ERROR] [$module] $*" >&2
    }
fi
